package com.own.component.common.util.list;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * MapUtil
 *
 * @author chenxueli
 * @date 2023-04-18 10:23:00
 */
@Slf4j
public class MapUtil {

    /**
     * 分组
     *
     * @param item          原对象
     * @param keyFunction   key函数
     * @param valueFunction value函数
     * @param <T>           原对象类型
     * @param <KEY>         key类型
     * @param <VALUE>       value类型
     * @return 分组后的map
     */
    public static <T, KEY, VALUE> Map<KEY, List<VALUE>> group(T item, Function<T, List<KEY>> keyFunction, Function<T, VALUE> valueFunction) {
        var keys = keyFunction.apply(item);
        if (keys == null || keys.isEmpty()) {
            return new HashMap<>();
        }
        var value = valueFunction.apply(item);
        return group(keys, value);
    }

    /**
     * 分组
     *
     * @param list    集合
     * @param item    集合中的元素
     * @param <KEY>   集合中的key元素类型
     * @param <VALUE> 集合中的value元素类型
     * @return 分组后的map
     */
    public static <KEY, VALUE> Map<KEY, List<VALUE>> group(List<KEY> list, VALUE item) {
        return group(list, item, null);
    }

    /**
     * 分组
     *
     * @param list    集合
     * @param item    集合中的元素
     * @param map     结果对象
     * @param <KEY>   集合中的key元素类型
     * @param <VALUE> 集合中的value元素类型
     * @return 分组后的map
     */
    public static <KEY, VALUE> Map<KEY, List<VALUE>> group(List<KEY> list, VALUE item, Map<KEY, List<VALUE>> map) {
        if (map == null) {
            map = new HashMap<>();
        }
        for (var client : list) {
            if (client != null) {
                if (!map.containsKey(client)) {
                    map.put(client, new ArrayList<>());
                }
                map.get(client).add(item);
            }
        }
        return map;
    }

}
